package com.cryptoneedle.center.source.entity.constraint;


import com.bubbles.engine.data.core.entity.BaseEntity;
import com.cryptoneedle.center.source.entity.metadata.SourceColumn;
import com.cryptoneedle.center.source.entity.metadata.SourceTable;
import com.cryptoneedle.center.source.key.constraint.SourceConstraintColumnKey;
import com.cryptoneedle.center.source.key.metadata.SourceColumnKey;
import com.cryptoneedle.center.source.key.metadata.SourceTableKey;
import jakarta.persistence.*;
import lombok.*;
import lombok.experimental.Accessors;
import org.hibernate.annotations.Comment;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

/**
 * <p>description: 源数据源-外键约束 </p>
 *
 * @author CryptoNeedle
 * @date 2025-06-20
 */
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true, exclude = {"sourceTable", "sourceColumn"})
@ToString(callSuper = true, exclude = {"sourceTable", "sourceColumn"})
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(schema = "public", name = "source_constraint_foreign")
@IdClass(SourceConstraintColumnKey.class)
@Comment("源数据源-外键约束")
public class SourceConstraintForeign extends BaseEntity {
    
    @Id
    @Comment("源数据源-目录名称")
    private String sourceCatalogName;
    
    @Id
    @Comment("源数据源-数据库名称")
    private String sourceDatabaseName;
    
    @Id
    @Comment("源数据源-表名称")
    private String sourceTableName;
    
    @Id
    @Comment("源数据源-约束名称")
    private String sourceConstraintName;
    
    @Id
    @Comment("源数据源-列名称")
    private String sourceColumnName;
    
    @Comment("源数据源-主表名称")
    private String foreignTableName;
    
    @Comment("源数据源-主表列")
    private String foreignColumnName;
    
    @Comment("源数据源-排序")
    private Integer position;
    
    // todo Enum Field
    @Comment("源数据源-删除规则")
    private String deleteRule;
    
    @Comment("源数据源-启用约束")
    private Boolean sourceColumnEnabled;
    
    /**
     * 关联关系
     */
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumns({@JoinColumn(name = "sourceCatalogName", referencedColumnName = "sourceCatalogName", insertable = false, updatable = false), @JoinColumn(name = "sourceDatabaseName", referencedColumnName = "sourceDatabaseName", insertable = false, updatable = false), @JoinColumn(name = "sourceTableName", referencedColumnName = "sourceTableName", insertable = false, updatable = false)})
    private SourceTable sourceTable;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumns({@JoinColumn(name = "sourceCatalogName", referencedColumnName = "sourceCatalogName", insertable = false, updatable = false), @JoinColumn(name = "sourceDatabaseName", referencedColumnName = "sourceDatabaseName", insertable = false, updatable = false), @JoinColumn(name = "foreignTableName", referencedColumnName = "sourceTableName", insertable = false, updatable = false), @JoinColumn(name = "foreignColumnName", referencedColumnName = "sourceColumnName", insertable = false, updatable = false)})
    private SourceColumn sourceColumn;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumns({@JoinColumn(name = "sourceCatalogName", referencedColumnName = "sourceCatalogName", insertable = false, updatable = false), @JoinColumn(name = "sourceDatabaseName", referencedColumnName = "sourceDatabaseName", insertable = false, updatable = false), @JoinColumn(name = "sourceTableName", referencedColumnName = "sourceTableName", insertable = false, updatable = false)})
    private SourceTable foreignTable;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumns({@JoinColumn(name = "sourceCatalogName", referencedColumnName = "sourceCatalogName", insertable = false, updatable = false), @JoinColumn(name = "sourceDatabaseName", referencedColumnName = "sourceDatabaseName", insertable = false, updatable = false), @JoinColumn(name = "foreignTableName", referencedColumnName = "sourceTableName", insertable = false, updatable = false), @JoinColumn(name = "foreignColumnName", referencedColumnName = "sourceColumnName", insertable = false, updatable = false)})
    private SourceColumn foreignColumn;
    
    /**
     * 其他
     */
    
    public SourceConstraintColumnKey getKey() {
        return new SourceConstraintColumnKey()
                .setSourceCatalogName(this.sourceCatalogName)
                .setSourceDatabaseName(this.sourceDatabaseName)
                .setSourceTableName(this.sourceTableName)
                .setSourceConstraintName(this.sourceConstraintName)
                .setSourceColumnName(this.sourceColumnName);
    }
    
    public String getStringKey() {
        return getKey().toString();
    }
    
    public String getTableStringKey() {
        return new SourceTableKey()
                .setSourceCatalogName(this.sourceCatalogName)
                .setSourceDatabaseName(this.sourceDatabaseName)
                .setSourceTableName(this.sourceTableName)
                .toString();
    }
    
    public String getColumnStringKey() {
        return new SourceColumnKey()
                .setSourceCatalogName(this.sourceCatalogName)
                .setSourceDatabaseName(this.sourceDatabaseName)
                .setSourceTableName(this.sourceTableName)
                .setSourceColumnName(this.sourceColumnName)
                .toString();
    }
}
